﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WpfApplication1;

using OutlookCalendar.Model;

namespace OutlookCalendar.Controls
{
    public class Calendar : Control
    {
        public static DateTime StartOfWeek(DateTime dt, DayOfWeek startOfWeek)
        {
            int diff = dt.DayOfWeek - startOfWeek;
            if (diff < 0)
            {
                diff += 7;
            }

            return dt.AddDays(-1 * diff).Date;
        }

       
        static Calendar()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Calendar), new FrameworkPropertyMetadata(typeof(Calendar)));
            
            CommandManager.RegisterClassCommandBinding(typeof(Calendar), new CommandBinding(NextDay, new ExecutedRoutedEventHandler(OnExecutedNextDay), new CanExecuteRoutedEventHandler(OnCanExecuteNextDay)));
            CommandManager.RegisterClassCommandBinding(typeof(Calendar), new CommandBinding(PreviousDay, new ExecutedRoutedEventHandler(OnExecutedPreviousDay), new CanExecuteRoutedEventHandler(OnCanExecutePreviousDay)));
            //FilterAppointments();
        }

        #region AddAppointment

        public static readonly RoutedEvent AddAppointmentEvent = 
            CalendarTimeslotItem.AddAppointmentEvent.AddOwner(typeof(CalendarDay));

        public event RoutedEventHandler AddAppointment
        {
            add
            {
                AddHandler(AddAppointmentEvent, value);
            }
            remove
            {
                RemoveHandler(AddAppointmentEvent, value);
            }
        }

        #endregion

        #region Appointments

        public static readonly DependencyProperty AppointmentsProperty =
            DependencyProperty.Register("Appointments", typeof(IEnumerable<Appointment>), typeof(Calendar),
            new FrameworkPropertyMetadata(null, new PropertyChangedCallback(Calendar.OnAppointmentsChanged)));

        public IEnumerable<Appointment> Appointments
        {
            get { return (IEnumerable<Appointment>)GetValue(AppointmentsProperty); }
            set { SetValue(AppointmentsProperty, value); }
        }

        private static void OnAppointmentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Calendar)d).OnAppointmentsChanged(e);
        }

        protected virtual void OnAppointmentsChanged(DependencyPropertyChangedEventArgs e)
        {
            FilterAppointments();
        }

        #endregion        
       
        #region CurrentDate

        /// <summary>
        /// CurrentDate Dependency Property
        /// </summary>
        public static readonly DependencyProperty CurrentDateProperty =
            DependencyProperty.Register("CurrentDate", typeof(DateTime), typeof(Calendar),
                new FrameworkPropertyMetadata((DateTime)DateTime.Now,
                    new PropertyChangedCallback(OnCurrentDateChanged)));
       // StartOfWeek(DateTime.Now,DayOfWeek.Monday)
        /// <summary>
        /// Gets or sets the CurrentDate property.  This dependency property 
        /// indicates ....
        /// </summary>
        public DateTime CurrentDate
        {
            get { return (DateTime)GetValue(CurrentDateProperty); }
            set { SetValue(CurrentDateProperty, value); }
        }

        /// <summary>
        /// Handles changes to the CurrentDate property.
        /// </summary>
        private static void OnCurrentDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Calendar)d).OnCurrentDateChanged(e);
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the CurrentDate property.
        /// </summary>
        protected virtual void OnCurrentDateChanged(DependencyPropertyChangedEventArgs e)
        {
            FilterAppointments();
        }

        #endregion             
        
        public void FilterAppointments()
        {
            
            DateTime byDate = Functionality.GetFirstDateOfWeek(CurrentDate,DayOfWeek.Monday);
            Functionality.LoadAppointmentsByDate(byDate, byDate + TimeSpan.FromDays(6));
            CalendarDay day = this.GetTemplateChild("day") as CalendarDay;
            day.ItemsSource = Appointments.ByDate(byDate);
            CalendarDay day1 = this.GetTemplateChild("day1") as CalendarDay;
            day1.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(1));
            CalendarDay day2 = this.GetTemplateChild("day2") as CalendarDay;
            day2.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(2));
            CalendarDay day3 = this.GetTemplateChild("day3") as CalendarDay;
            day3.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(3));
            CalendarDay day4 = this.GetTemplateChild("day4") as CalendarDay;
            day4.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(4));
            CalendarDay day5 = this.GetTemplateChild("day5") as CalendarDay;
            day5.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(5));
            CalendarDay day6 = this.GetTemplateChild("day6") as CalendarDay;
            day6.ItemsSource = Appointments.ByDate(byDate + TimeSpan.FromDays(6));
            

            TextBlock dayHeader = this.GetTemplateChild("dayHeader") as TextBlock;
            TextBlock dayHeader1 = this.GetTemplateChild("dayHeader1") as TextBlock;
            TextBlock dayHeader2 = this.GetTemplateChild("dayHeader2") as TextBlock;
            TextBlock dayHeader3 = this.GetTemplateChild("dayHeader3") as TextBlock;
            TextBlock dayHeader4 = this.GetTemplateChild("dayHeader4") as TextBlock;
            TextBlock dayHeader5 = this.GetTemplateChild("dayHeader5") as TextBlock;
            TextBlock dayHeader6 = this.GetTemplateChild("dayHeader6") as TextBlock;
            //dayHeader.Text = byDate.DayOfWeek.ToString();

            dayHeader.Text = "Pirmadienis " + byDate.Year+"."+(byDate.Month.ToString().Length == 2 ? byDate.Month.ToString() : "0" + byDate.Month.ToString()) + "." + (byDate.Day.ToString().Length == 2 ? byDate.Day.ToString() : "0" + byDate.Day.ToString());
            dayHeader1.Text = "Antradienis " + (byDate + TimeSpan.FromDays(1)).Year+"."+((byDate + TimeSpan.FromDays(1)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(1)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(1)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(1)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(1)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(1)).Day.ToString());
            dayHeader2.Text = "Trečiadienis " + (byDate + TimeSpan.FromDays(2)).Year + "." + ((byDate + TimeSpan.FromDays(2)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(2)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(2)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(2)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(2)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(2)).Day.ToString());
            dayHeader3.Text = "Ketvirtadienis " + (byDate + TimeSpan.FromDays(3)).Year + "." + ((byDate + TimeSpan.FromDays(3)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(3)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(3)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(3)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(3)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(3)).Day.ToString());
            dayHeader4.Text = "Penktadienis " + (byDate + TimeSpan.FromDays(4)).Year + "." + ((byDate + TimeSpan.FromDays(4)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(4)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(4)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(4)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(4)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(4)).Day.ToString());
            dayHeader5.Text = "Šeštadienis " + (byDate + TimeSpan.FromDays(5)).Year + "." + ((byDate + TimeSpan.FromDays(5)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(5)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(5)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(5)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(5)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(5)).Day.ToString());
            dayHeader6.Text = "Sekmadienis " + (byDate + TimeSpan.FromDays(6)).Year + "." + ((byDate + TimeSpan.FromDays(6)).Month.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(6)).Month.ToString() : "0" + (byDate + TimeSpan.FromDays(6)).Month.ToString()) + "." + ((byDate + TimeSpan.FromDays(6)).Day.ToString().Length == 2 ? (byDate + TimeSpan.FromDays(6)).Day.ToString() : "0" + (byDate + TimeSpan.FromDays(6)).Day.ToString());
        }

        #region NextDay/PreviousDay

        public static readonly RoutedCommand NextDay = new RoutedCommand("NextDay", typeof(Calendar));
        public static readonly RoutedCommand PreviousDay = new RoutedCommand("PreviousDay", typeof(Calendar));

        private static void OnCanExecuteNextDay(object sender, CanExecuteRoutedEventArgs e)
        {
            ((Calendar)sender).OnCanExecuteNextDay(e);
        }

        private static void OnExecutedNextDay(object sender, ExecutedRoutedEventArgs e)
        {
            ((Calendar)sender).OnExecutedNextDay(e);
        }

        protected virtual void OnCanExecuteNextDay(CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = false;
        }

        protected virtual void OnExecutedNextDay(ExecutedRoutedEventArgs e)
        {
            CurrentDate += TimeSpan.FromDays(7);
            e.Handled = true;            
        }

        private static void OnCanExecutePreviousDay(object sender, CanExecuteRoutedEventArgs e)
        {
            ((Calendar)sender).OnCanExecutePreviousDay(e);
        }

        private static void OnExecutedPreviousDay(object sender, ExecutedRoutedEventArgs e)
        {
            ((Calendar)sender).OnExecutedPreviousDay(e);
        }

        protected virtual void OnCanExecutePreviousDay(CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
            e.Handled = false;
        }

        protected virtual void OnExecutedPreviousDay(ExecutedRoutedEventArgs e)
        {
            CurrentDate -= TimeSpan.FromDays(7);
            e.Handled = true;
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            //Cursor.Position = new Point(Cursor.Position.X + 10, Cursor.Position.Y + 10);
            base.OnMouseDown(e);

            TextBlock dayHeader = this.GetTemplateChild("dayHeader") as TextBlock;
            TextBlock dayHeader1 = this.GetTemplateChild("dayHeader1") as TextBlock;
            TextBlock dayHeader2 = this.GetTemplateChild("dayHeader2") as TextBlock;
            TextBlock dayHeader3 = this.GetTemplateChild("dayHeader3") as TextBlock;
            TextBlock dayHeader4 = this.GetTemplateChild("dayHeader4") as TextBlock;
            TextBlock dayHeader5 = this.GetTemplateChild("dayHeader5") as TextBlock;
            TextBlock dayHeader6 = this.GetTemplateChild("dayHeader6") as TextBlock;

            if (dayHeader.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day";
            }
            if (dayHeader1.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day1";
            }
            if (dayHeader2.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day2";
            }
            if (dayHeader3.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day3";
            }
            if (dayHeader4.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day4";
            }
            if (dayHeader5.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day5";
            }
            if (dayHeader6.Foreground.Equals(Brushes.Red))
            {
                Functionality.CalendarDayOfWeek = "day6";
            }
           

            CalendarDay day = this.GetTemplateChild("day") as CalendarDay;
            CalendarDay day1 = this.GetTemplateChild("day1") as CalendarDay;
            CalendarDay day2 = this.GetTemplateChild("day2") as CalendarDay;
            CalendarDay day3 = this.GetTemplateChild("day3") as CalendarDay;
            CalendarDay day4 = this.GetTemplateChild("day4") as CalendarDay;
            CalendarDay day5 = this.GetTemplateChild("day5") as CalendarDay;
            CalendarDay day6 = this.GetTemplateChild("day6") as CalendarDay;

            switch (Functionality.CalendarDayOfWeek)
            {
                case "day": day.Background = Brushes.Red; day1.Background = null; day2.Background = null; day3.Background = null; day4.Background = null; day5.Background = null; day6.Background = null; break;
                case "day1": day.Background = null; day1.Background = Brushes.Red; day2.Background = null; day3.Background = null; day4.Background = null; day5.Background = null; day6.Background = null; break;
                case "day2": day.Background = null; day1.Background = null; day2.Background = Brushes.Red; day3.Background = null; day4.Background = null; day5.Background = null; day6.Background = null; break;
                case "day3": day.Background = null; day1.Background = null; day2.Background = null; day3.Background = Brushes.Red; day4.Background = null; day5.Background = null; day6.Background = null; break;
                case "day4": day.Background = null; day1.Background = null; day2.Background = null; day3.Background = null; day4.Background = Brushes.Red; day5.Background = null; day6.Background = null; break;
                case "day5": day.Background = null; day1.Background = null; day2.Background = null; day3.Background = null; day4.Background = null; day5.Background = Brushes.Red; day6.Background = null; break;
                case "day6": day.Background = null; day1.Background = null; day2.Background = null; day3.Background = null; day4.Background = null; day5.Background = null; day6.Background = Brushes.Red; break;
                default: day.Background = null; day1.Background = null; day2.Background = null; day3.Background = null; day4.Background = null; day5.Background = null; day6.Background = null; break;
            }
           // MessageBox.Show("taip");
        }

        #endregion
    }
}
